package cn.com.xy.sms.sdk.ui.web;

import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.webkit.ConsoleMessage;
import android.webkit.DownloadListener;
import android.webkit.GeolocationPermissions.Callback;
import android.webkit.WebSettings.RenderPriority;
import android.webkit.WebSettings.TextSize;
import android.webkit.JsResult;
import android.webkit.SslErrorHandler;
import android.webkit.WebSettings;
import android.webkit.WebView;
import cn.com.xy.sms.sdk.ui.R;
import cn.com.xy.sms.sdk.ui.popu.util.SmartSmsSdkUtil;
import cn.com.xy.sms.sdk.ui.popu.util.XySdkUtil;
import cn.com.xy.sms.sdk.Iservice.OnlineUpdateCycleConfigInterface;
import cn.com.xy.sms.sdk.constant.Constant;
import cn.com.xy.sms.sdk.dex.DexUtil;
import cn.com.xy.sms.sdk.net.NetWebUtil;
import cn.com.xy.sms.sdk.util.DuoquUtils;
import cn.com.xy.sms.sdk.util.JsonUtil;
import cn.com.xy.sms.sdk.util.KeyManager;
import cn.com.xy.sms.sdk.util.StringUtils;
import cn.com.xy.sms.sdk.util.XyUtil;
import cn.com.xy.sms.util.ParseManager;

public class SdkWebViewManager implements IActivityParamForJS {
    public static final int CONFIG_WEB_TOP_MENU = 2;
    
    private String mChannelId;
    private String mSdkVersion;
    private IActivityForWebView mWebAcitvity;
    private WebView mWebView = null;
    private String mActionType;

    private String mXid = "";
    private String mPid = "";
    private String mUv = "";
    private String mAi = "";
    private String mNi = "";

    public SdkWebViewManager(final IActivityForWebView webAcitvity) {
        if(webAcitvity == null){
            return;
        }
        mWebAcitvity = webAcitvity;
        mWebView = webAcitvity.getWebView();
        
        Context c= mWebAcitvity.getActivity();
        if(c != null){
            mDuoquText = c.getResources().getString(R.string.duoqu_tip_duoqu_name_ui);
        }
        
        try{
            initWebView();
        }catch(Throwable e){
            
        }
        new Thread(new InitRunnable()).start();
    }
    
    private class InitRunnable implements Runnable {
        @Override
        public void run() {
            try {
                Context c= mWebAcitvity.getActivity();
                if(c != null){
                    
                }
                initParams(c.getApplicationContext());
                mHandler.obtainMessage(MSG_TYPE_LOADURL).sendToTarget();
            } catch (Throwable e) {

            }
        }

    }

    @SuppressLint("SetJavaScriptEnabled")
    private void initWebView() {

        if (mWebAcitvity == null || mWebView == null) {
            return;
        }

        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
        mWebView.getSettings().setBuiltInZoomControls(true);
        mWebView.getSettings().setDomStorageEnabled(true); // open DOM storage
        
        mWebView.getSettings().setLoadWithOverviewMode(true);
        mWebView.getSettings().setUseWideViewPort(true);// support h5 view port
        mWebView.getSettings().setDatabaseEnabled(true);
        mWebView.getSettings().setTextSize(TextSize.NORMAL);
        mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
        mWebView.getSettings().setRenderPriority(RenderPriority.HIGH);
        mWebView.getSettings().setBlockNetworkImage(true);
        
        if(mWebAcitvity.getActivity() != null){
            String dir = mWebAcitvity.getActivity().getApplicationContext().getDir("database", Context.MODE_PRIVATE)
                    .getPath();

            mWebView.getSettings().setGeolocationDatabasePath(dir);
        }
        
        mWebView.getSettings().setGeolocationEnabled(true);
                                                                        // 缓存模式
        mWebView.setDownloadListener(new DownloadListener() {
            @Override
            public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype,
                    long contentLength) {
                mWebAcitvity.onDownloadStart(url, userAgent, contentDisposition, mimetype, contentLength);
            }
        });
        
        // API function
        mWebView.setWebViewClient(new CommonWebViewClientEx() {
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                if(mWebAcitvity != null){
                    mWebAcitvity.onReceivedSslError(view, handler, error);
                }
            }

            // Response to a hyperlink
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if(mWebAcitvity != null){
                    return mWebAcitvity.shouldOverrideUrlLoading(view, url);
                }else{
                    return false;
                }
            }

            // start loading
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                if(mWebAcitvity != null){
                    mWebAcitvity.onPageStarted(view, url,favicon);
                }
            }
            
            @Override
            public void onPageFinished(WebView view, String url) {
                if(mWebAcitvity != null){
                    mWebAcitvity.onPageFinished(view, url);
                }
                super.onPageFinished(view, url);
            }

            // Handle the abnormal case
            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                if(mWebAcitvity != null){
                    mWebAcitvity.onReceivedError(view, errorCode, description, failingUrl);
                    mWebAcitvity.setEndUrl(failingUrl);
                }
            }
        });

        mWebView.setWebChromeClient(new CommonWebChromeClientEx() {
            @Override
            @Deprecated
            public void onConsoleMessage(String message, int lineNumber, String sourceID) {
                super.onConsoleMessage(message, lineNumber, sourceID);
                if(mWebAcitvity != null){
                    mWebAcitvity.onConsoleMessage(message,lineNumber,sourceID);
               }
            }

            @Override
            public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {
                super.onGeolocationPermissionsShowPrompt(origin, callback);
                if(mWebAcitvity != null){
                     mWebAcitvity.onGeolocationPermissionsShowPrompt(origin,callback);
                }else{
                    callback.invoke(origin, true, false);
                }
            }

            @Override
            public boolean onConsoleMessage(ConsoleMessage cm) {
                if(mWebAcitvity != null){
                    return mWebAcitvity.onConsoleMessage(cm);
                }else{
                    return true;
                }
            }

            public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
               if(mWebAcitvity == null){
                   return false;
               }
               
               return mWebAcitvity.onJsAlert(view,url,message,result);
            };

            public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
                if(mWebAcitvity == null){
                    return false;
                }

                return mWebAcitvity.onJsConfirm(view,url,message,result);
            };

            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                if (newProgress == 100) {
                    mSdkJs.postData(true);
                }
                mWebAcitvity.onProgressChanged(view, newProgress);
                super.onProgressChanged(view, newProgress);
                view.requestFocus();
            }

            /**
             * set web view title
             */
            public void onReceivedTitle(WebView view, String title) {
                if(mWebAcitvity == null){
                    return;
                }
                mWebAcitvity.onReceivedTitle(view,title);
                super.onReceivedTitle(view, title);
            }
        });

        mSdkJs = new SdkWebJavaScript(this);
        mWebView.addJavascriptInterface(mSdkJs, "injs");
    }

    /**
     * Load the URL
     */
    private void loadWebViewUrl() {
        initData();
        if(mIntent == null || mWebAcitvity == null){
            return;
        }
        String aType = mIntent.getStringExtra("actionType");
        mActionType = getParamData("type");
        String pageViewUrl = null;
        mSdkJs.queryJson(mActionType, JsonUtil.jsonObjectToString(mJsObj), true);
        if (aType != null && "WEB_URL".equals(aType)) {
            pageViewUrl = getParamData("url");
        } else {
            String host = getParamData("HOST");

            if (StringUtils.isNull(host)) {
                host = NetWebUtil.WEB_SERVER_URL;
            }
            pageViewUrl = getParamData("PAGEVIEW");
            if (StringUtils.isNull(pageViewUrl)) {

                if ("WEB_MAP_SITE".equals(mActionType)) {
                    String address = getParamData("address");
                    pageViewUrl = "http://api.map.baidu.com/geocoder?address=" + address + "&output=html&src=xiaoyuan|"
                            + mDuoquText;

                    if (!StringUtils.isNull(address)) {
                        mWebAcitvity.requestWebViewLoad(pageViewUrl);
                    } else {
                        mWebAcitvity.showError(ERROR_TYPE_OTHER, null);
                    }
                    return;
                } else {
                    pageViewUrl = "h5service?action_type=" + mActionType + "&xy_channel=" + mChannelId + "&xy_sdkver="
                            + mSdkVersion;
                }
            }
            if (!StringUtils.isNull(pageViewUrl)) {
                pageViewUrl = host + "/" + pageViewUrl;
            }
        }
        if (!StringUtils.isNull(pageViewUrl)) {
            int isNetWork = XyUtil.checkNetWork(mWebAcitvity.getActivity());
            if (isNetWork == 0 || isNetWork == 1) {
                Map<String, String> header = getHttpRequsetHeader(pageViewUrl);
                if (header == null) {
                    header = new HashMap<String, String>();
                }
                // header.put("xy-url", pageViewUrl);
                /* SERVER-62 xusongzhou 20160413 start */
                header.put("xy-channel", mChannelId);
                header.put("xy-sdk-ver", mSdkVersion);
                header.put("xy-req-time", String.valueOf(new Date().getTime()));
                header.put("xy-x", mXid);
                header.put("xy-p", mPid);
                if (getParamData("menuName") != null || "".equals(getParamData("menuName"))) {
                    try {
                        String encodeMenuName = URLEncoder.encode(getParamData("menuName"), "utf-8");
                        header.put("xy-menu-name", encodeMenuName);
                    } catch (Throwable e) {
                        SmartSmsSdkUtil.smartSdkExceptionLog("SdkWebActivity error ", e);
                    }
                }
                if (getParamData("publicId") != null || "".equals(getParamData("publicId"))) {
                    try {
                        String encodePublicId = URLEncoder.encode(getParamData("publicId"), "utf-8");
                        header.put("xy-public-id", encodePublicId);
                    } catch (Throwable e) {
                        SmartSmsSdkUtil.smartSdkExceptionLog("SdkWebActivity error ", e);
                    }
                }
                mWebAcitvity.requestWebViewLoad(pageViewUrl,header);
                //mWebView.loadUrl(pageViewUrl, header);
                /* SERVER-62 xusongzhou 20160413 end */
            } else {
                mWebAcitvity.showError(ERROR_TYPE_NO_NET_WORK, null);
                mWebAcitvity.setEndUrl(pageViewUrl);
            }

        } else {
            mWebAcitvity.showError(ERROR_TYPE_OTHER, null);
        }
    }
    
    public final static int ERROR_TYPE_OTHER = 1;
    public final static int ERROR_TYPE_NO_NET_WORK = 2;
    
    private JSONObject mJsObj = null;
    private Intent mIntent = null;
    private SdkWebJavaScript mSdkJs;
    private String mDuoquText;
    
    private void initData() {
        if(mWebAcitvity == null){
            return;
        }
        
        try {
            if (mJsObj == null) {
                mIntent = mWebAcitvity.getIntent();
                if(mIntent != null){
                    String jsonData = mIntent.getStringExtra("JSONDATA");
                    mJsObj = new JSONObject(jsonData);
                }
            }
        } catch (Throwable e) {
        }
    }

    public String getParamData(String key) {
        String res = null;
        if (key != null) {
            try {
                if (mJsObj == null) {
                    mIntent = mWebAcitvity.getIntent();
                    if(mIntent != null){
                        String jsonData = mIntent.getStringExtra("JSONDATA");
                        mJsObj = new JSONObject(jsonData);
                    }
                }
                if (mJsObj != null && mJsObj.has(key)) {
                    res = mJsObj.getString(key);
                }
            } catch (Throwable e) {
                SmartSmsSdkUtil.smartSdkExceptionLog("SdkWebActivity error ", e);
            }
        }
        if (res == null){
            res = "";
        }
        return res;
    }
    
    public void setParamData(String key, String value) {
        if (StringUtils.isNull(key)){
            return;
        }
        try {
            if (mJsObj == null) {
                mIntent = mWebAcitvity.getIntent();
                if(mIntent != null){
                    String jsonData = mIntent.getStringExtra("JSONDATA");
                    mJsObj = new JSONObject(jsonData);
                }
            }
            if (mJsObj != null) {
                mJsObj.put(key, value);
            }
        } catch (Throwable e) {
            SmartSmsSdkUtil.smartSdkExceptionLog("SdkWebActivity error ", e);
        }
    }
    
    public static final int MSG_TYPE_CONVERSATION = 1;
    public static final int MSG_TYPE_LOADURL = 2;
    
    private JSONObject mConversation = null;
    private boolean mIsWebViewLoaded = false;
    private boolean mIsCallBackData = false;

    private Handler mHandler = new Handler(Looper.getMainLooper()){
        public void handleMessage(Message msg) {
            switch(msg.what){
                case MSG_TYPE_CONVERSATION:
                    doConversationStateChange();
                    break;
                case MSG_TYPE_LOADURL:
                    mWebAcitvity.onSdkParamsInitfinish();
                    loadWebViewUrl();
                    break;
                default:
            }
        }
    };
    
    private void doConversationStateChange() {
        if(!mIsCallBackData && mIsWebViewLoaded && mConversation != null && mWebView != null){
            mIsCallBackData = true;
            mWebView.post(new Runnable() {
                @Override
                public void run() {
                    mWebView.loadUrl(
                               "javascript:" + "callBackData" + "('"
                                       + JsonUtil.jsonObjectToString(mConversation) + "')");
                }
            });
        }
    }
    
    public void setData(int type, Object data){
        switch(type){
            case SdkWebJavaScript.DATA_TYPE_CONVERSATION:
                mConversation = (JSONObject)data;
                sendConversationDataChange();
                break;
            case SdkWebJavaScript.DATA_TYPE_CONVERSATION_CARD_READY:
            case SdkWebJavaScript.DATA_TYPE_CONVERSATION_TRAIN_READY:
                /* notify webView finish loaded */
                mIsWebViewLoaded = true;
                sendConversationDataChange();
                break;
            default:
        }
    }
    
    private void sendConversationDataChange(){
        if(mHandler != null ){
            mHandler.removeMessages(MSG_TYPE_CONVERSATION);
            mHandler.obtainMessage(MSG_TYPE_CONVERSATION).sendToTarget();
        }
    }

    /**
     * set title from menu name
     * 
     * @param title
     * @param menuName
     */
    public String getTitle(String menuName, String title) {
        if (StringUtils.isNull(menuName)) {
            return menuName;
        } else {
            return title;
        }
    }

    public void postData(final JSONObject json, boolean changeFlag) {
        if(mWebView != null){
            mWebView.post(new Runnable() {
                @Override
                public void run() {
                    if(mWebView != null){
                        mWebView.loadUrl(
                            "javascript:" + "callBackData" + "('" + JsonUtil.jsonObjectToString(json) + "')");
                    }
                }
            });
        }
    }

    /**
     * init some params from sdk
     */
    public void initParams(Context context) {
        try {
            Constant.initContext(context);
            KeyManager.initAppKey();
            mChannelId = KeyManager.getAppKey();
            mSdkVersion = ParseManager.getSdkVersion();
            mXid = DuoquUtils.getXid();
            mPid = DuoquUtils.getPid();
            mUv = ParseManager.getUIVersion();
            mAi = DuoquUtils.getAI();
            mNi = DuoquUtils.getNI();
        } catch (Throwable e) {
            SmartSmsSdkUtil.smartSdkExceptionLog("SdkWebActivity error ", e);
        }
    }

    public void doDestroy() {
        if(mWebAcitvity == null || mWebAcitvity.getActivity() == null){
            return;
        }
        
        if (mJsObj == null) {
            mIntent = mWebAcitvity.getIntent();
            if(mIntent != null){
                String jsonData = mIntent.getStringExtra("JSONDATA");
                try {
                    mJsObj = new JSONObject(jsonData);
                } catch (Throwable e) {
                    SmartSmsSdkUtil.smartSdkExceptionLog("SdkWebActivity error ", e);
                }
            }
        }
        
        Intent intent = new Intent();
        if (mJsObj != null) {
            intent.putExtra("JSONDATA", mJsObj.toString());

            String type = mJsObj.optString("type","");
            String resverFilag = "";
            if(type.equals("WEB_QUERY_EXPRESS_FLOW")){
                resverFilag = "cn.com.xy.sms.ExpressStatusReceiver";
                /*HUAWEI-1324/zhegnxiaobo 2016.07.07 start*/   
            }else if("WEB_QUERY_FLIGHT_TREND".equals(type)){
                resverFilag = "cn.com.xy.sms.FlightStateQueryReceiver";
                /*HUAWEI-1324/zhegnxiaobo 2016.07.07 end*/ 
            }else{
                resverFilag = "cn.com.xy.sms.TrianStationSelectedReceiver";
            }
            intent.setAction(resverFilag);
    
            mWebAcitvity.getActivity().sendBroadcast(intent);
        }
    }

    @Override
    public String getType() {
        return getParamData("type");
    }

    @Override
    public WebView getWebView() {
        return mWebView;
    }

    @Override
    public Activity getActivity() {
        if(mWebAcitvity != null){
            return mWebAcitvity.getActivity();
        }
        return null;
    }

    @Override
    public int checkOrientation() {
        if(mWebAcitvity != null){
            return mWebAcitvity.checkOrientation();
        }
        return 0;
    }
    
    public Map<String, String> getHttpRequsetHeader(String url) {
        Context c = getActivity();
        if(c == null){
            return null;
        }
        String referer = DexUtil.getOnLineConfigureData(OnlineUpdateCycleConfigInterface.CONFIG_URL_REFERER);
        if (StringUtils.isNull(referer)) {
            referer = "bizport.cn/66dc91e8b78b1c284027a3eb1be0a70e";
        }
        Map<String, String> header = new HashMap<String, String>();
        header.put("app-key", mChannelId) ;
        header.put("x", mXid) ;
        header.put("p", mPid) ;
        header.put("sdkversion", mSdkVersion) ;
        header.put("uiversion", mUv) ;
        header.put("ai", mAi) ;
        header.put("ni", mNi) ;
        header.put("referer", referer) ;
        
        int type = XyUtil.checkNetWork(c, 1);
        int netWorkType = -1;
        if(type == 0){
            netWorkType = -1;
        }else{
            netWorkType = XySdkUtil.getDataNewWorkType(c);
        }
        header.put("net", String.valueOf(netWorkType));
        return header;
    }

}
